package com.pig4cloud.pig.module.service.charger.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.common.core.exception.TransactionalException;
import com.pig4cloud.pig.common.core.util.DateUtils;
import com.pig4cloud.pig.common.core.util.MathUtil;
import com.pig4cloud.pig.common.core.util.OrderUtil;
import com.pig4cloud.pig.common.core.wx.WxAppPay;
import com.pig4cloud.pig.module.api.entity.charger.ChargerEstateBattery;
import com.pig4cloud.pig.module.api.entity.charger.ChargerOrder;
import com.pig4cloud.pig.module.api.entity.charger.ChargerOrderDetailedList;
import com.pig4cloud.pig.module.api.entity.charger.ChargerUsedBattery;
import com.pig4cloud.pig.module.api.entity.dto.ChargerOrderDTO;
import com.pig4cloud.pig.module.api.entity.dto.ChargerOrderEcharts;
import com.pig4cloud.pig.module.api.entity.platform.PlatformPay;
import com.pig4cloud.pig.module.api.entity.splitAccount.SplitAccount;
import com.pig4cloud.pig.module.api.entity.splitAccount.SplitAccountRecord;
import com.pig4cloud.pig.module.api.entity.wx.WxPayTransaction;
import com.pig4cloud.pig.module.api.entity.wx.WxUser;
import com.pig4cloud.pig.module.mapper.charger.ChargerOrderMapper;
import com.pig4cloud.pig.module.service.base.IParameterService;
import com.pig4cloud.pig.module.service.charger.IChargerOrderService;
import com.pig4cloud.pig.module.service.platform.IPlatformPayService;
import com.pig4cloud.pig.module.service.splitAccount.ISplitAccountRecordService;
import com.pig4cloud.pig.module.service.splitAccount.ISplitAccountService;
import com.pig4cloud.pig.module.service.wx.IWxPayTransactionService;
import com.pig4cloud.pig.module.service.wx.IWxUserService;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 订单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-05-07
 */
@Service
public class ChargerOrderServiceImpl extends ServiceImpl<ChargerOrderMapper, ChargerOrder> implements IChargerOrderService {

	@Resource
	private ChargerOrderMapper chargerOrderMapper;
	@Resource
	private IPlatformPayService platformPayService;
	@Resource
	private ISplitAccountService splitAccountService;
	@Resource
	private ISplitAccountRecordService splitAccountRecordService;
	@Resource
	private IWxUserService wxUserService;
	@Resource
	private IWxPayTransactionService wxPayTransactionService;


	@Value("${web.wx_refund_notify_url}")
	private String wx_refund_notify_url;//微信支付的回调地址

	@Value("${web.appid}")
	private String appid;
	@Value("${web.secret}")
	private String secret;
	@Value("${web.mch_id}")
	private String mch_id;
	@Value("${web.api_key}")
	private String api_key;
	@Value("${web.keyPath}")
	private String keyPath;//微信支付的回调地址

	@Override
	public List<ChargerOrderDTO> selectChargerOrderTongji(Page<ChargerOrder> page, Map<String, Object> map) {
		return chargerOrderMapper.selectChargerOrderTongji(page,map);
	}

	@Override
	public List<ChargerUsedBattery> selectChargerUsedBattery(Page<ChargerUsedBattery> page, Map<String, Object> map) {
		return chargerOrderMapper.selectChargerUsedBattery(page,map);
	}

	@Override
	public List<ChargerOrderDetailedList> selectChargerOrderDetailedList(Map<String, Object> map) {
		return chargerOrderMapper.selectChargerOrderDetailedList(map);
	}

	@Override
	public List<ChargerOrderDTO> selectChargerOrderTongji(Map<String, Object> map) {
		return chargerOrderMapper.selectChargerOrderTongji(map);
	}

	@Override
	public ChargerOrderDTO selectOrderTongjiByEstateId(Map<String, Object> map) {
		return chargerOrderMapper.selectOrderTongjiByEstateId(map);
	}

	@Override
	public List<ChargerEstateBattery> selectChargerEstateBattery(Map<String, Object> map) {
		return chargerOrderMapper.selectChargerEstateBattery(map);
	}

	@Override
	public List<List<String>> getChargerByTop(int limit) {

		List<List<String>> dataList = new ArrayList<>();
		Map<String,Object> chargerChart = new HashMap<>();
//		[
//            ['product', '7月', '8月'],
//            ['丰园新区', 43.3, 85.8, ],
//            ['儒风海韵', 83.1, 73.4,],
//            ['日钢生活区', 86.4, 65.2,],
//            ['凌云佳苑', 72.4, 53.9,],
//            ['西湖小区', 72.4, 53.9,],
//            ['西湖尚品', 72.4, 53.9,]
//      ]
		List<String> monthStr = new ArrayList<>();
		monthStr.add("product");
		//近2个月
		Integer[] months = { -1, 0 };
		for (Integer month : months){
			List<String> data = new ArrayList<>();
			Map<String,Object> map = DateUtils.getMonthBy(month);
			monthStr.add(map.get("month_num") + "月");
			map.put("limit",6);
			List<ChargerOrderEcharts> list =  chargerOrderMapper.selectChargerOrderCharts(map);
			if(CollUtil.isNotEmpty(list)){
				for (ChargerOrderEcharts order: list){
					data.add(order.getEstateName());
					data.add(order.getEstateName());
				}
			}
		}

		dataList.add(monthStr);
		return dataList;
	}

	@Override
	@Transactional
	public int refundChargerOrder(ChargerOrder chargerOrder) {
		int ret = 0;
		try{
//			Parameter parameter = parameterService.getParameterById(1);
			PlatformPay platformPay = platformPayService.getDefaultAccount();
			//充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
			chargerOrder.setChargerState(3);
			double leftMoney = MathUtil.getDoubleUp(chargerOrder.getTotalPrice().doubleValue() - chargerOrder.getUsePrice().doubleValue());
			String out_refund_no = OrderUtil.getOrderNoByTimespan();
			if(chargerOrder.getPayPlatform() == 1){
				out_refund_no = platformPay.getSysCode() + OrderUtil.getOrderNoByTimespan();
			}
			chargerOrder.setRefundOutTradeNo(out_refund_no);
			//收费的充电,并且是微信支付  才发起退款
			if(chargerOrder.getIsFree() == 0) {
				if (chargerOrder.getPayType() == 0) {//微信支付 退款
					if (chargerOrder.getRefundStatus() == 0 || chargerOrder.getRefundStatus() == 1 || chargerOrder.getRefundStatus() == 3) {
						if (leftMoney > 0) {
							String retRequest = "";
							if(chargerOrder.getPayPlatform() == 0) {
								WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id, api_key);
								retRequest = wxAppPay.refundPayAPIStr(chargerOrder.getOutTradeNo(), chargerOrder.getPayPrice(), new BigDecimal(leftMoney), chargerOrder.getRefundOutTradeNo(), keyPath);
							} else {
								retRequest = platformPayService.refundOrder(chargerOrder.getOutTradeNo(), new BigDecimal(leftMoney),chargerOrder.getRefundOutTradeNo(),platformPay);
								System.out.println("retRequest: " + retRequest);
							}

							JSONObject jsonObject = JSONUtil.parseObj(retRequest);
							if (jsonObject != null) {
								String code = "";
								String msg = "";
								boolean bl = false;
								if(chargerOrder.getPayPlatform() == 0) {
									code = jsonObject.containsKey("code") ? jsonObject.getStr("code") : "";
									msg = jsonObject.containsKey("msg") ? jsonObject.getStr("msg") : "";

									if (code.equals("SUCCESS")) {
										bl = true;
									}
								}else{
									code = jsonObject.getStr("errCode");
									msg = jsonObject.getStr("errMsg");
									String refundStatus = jsonObject.getStr("refundStatus");

									if (code.equals("SUCCESS") && refundStatus.equals("SUCCESS")) {
										bl = true;
									}
								}

								if (bl) {
									//订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
									chargerOrder.setStatus(4);
									//0 未退款 1 申请中 2 已退款
									chargerOrder.setRefundStatus(1);
								} else {
									//订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
									chargerOrder.setStatus(6);
									chargerOrder.setChargerState(3);
									//0 未退款 1 申请中 2 已退款  3 - 失败
									chargerOrder.setRefundStatus(3);
								}
								chargerOrder.setRefundReason(msg);
							}
						} else {
							chargerOrder.setStatus(7);
						}
					}
				} else {
					chargerOrder.setStatus(7);
					chargerOrder.setRefundStatus(2);
					if(leftMoney > 0){
						chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
						// 退回剩余金额到 余额里面去
						SplitAccount splitAccount = splitAccountService.getAccountByUserId(chargerOrder.getUserId(),4,chargerOrder.getUserId());
						if(splitAccount != null){
							double chargerMoney = splitAccount.getChargerMoney().doubleValue();
							chargerMoney = chargerMoney + leftMoney;
							splitAccount.setChargerMoney(new BigDecimal(chargerMoney));
							boolean bl = splitAccountService.updateById(splitAccount);
							if(!bl){
								throw new TransactionalException("splitAccountService updateById error");
							}


							SplitAccountRecord accountRecord = new SplitAccountRecord();
							accountRecord.setUserId(chargerOrder.getUserId());
							accountRecord.setCreateTime(new Date());
							accountRecord.setAccountId(splitAccount.getId());
							accountRecord.setInOrOut(1);//进账
//						accountRecord.setCashRemark("");
							accountRecord.setSplitMoney(new BigDecimal(leftMoney));
//						accountRecord.setCashState(0);
							accountRecord.setRemark("充电退款到账户");
							accountRecord.setFromType(7);
							splitAccountRecordService.save(accountRecord);
						}
					}
				}
			} else {
				chargerOrder.setStatus(7);
				chargerOrder.setRefundStatus(2);
			}

			ret = chargerOrderMapper.updateById(chargerOrder);
			if(ret <= 0){
				throw new TransactionalException("chargerOrderMapper updateById error");
			}
//			wxTemplateService.sendWxMsgEndCharger(chargerOrder);
		}catch (Exception e){
			e.printStackTrace();
		}
		return ret;
	}

	@Override
	public int queryRefundChargerOrder(ChargerOrder chargerOrder) {
		int ret = 0;
		try{
			//<xml><appid><![CDATA[wx854289814b853175]]></appid>
			// <cash_fee><![CDATA[100]]></cash_fee><
			// cash_refund_fee_0><![CDATA[100]]></cash_refund_fee_0>
			// <mch_id><![CDATA[1613461126]]></mch_id>
			// <nonce_str><![CDATA[dwz12r5HzeMILsOI]]></nonce_str>
			// <out_refund_no_0><![CDATA[10001660710323517]]></out_refund_no_0>
			// <out_trade_no><![CDATA[00000001660709136736]]></out_trade_no>
			// <refund_account_0><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]>
			// </refund_account_0><refund_channel_0>
			// <![CDATA[ORIGINAL]]>
			// 	</refund_channel_0>
			// 			<refund_count>1</refund_count>
			// 			<refund_fee>100</refund_fee>
			// 			<refund_fee_0>100</refund_fee_0>
			// 			<refund_id_0><![CDATA[50301703032022081723857642095]]></refund_id_0>
			// 			<refund_recv_accout_0><![CDATA[支付用户零钱]]></refund_recv_accout_0>
			// 			<refund_status_0><![CDATA[SUCCESS]]></refund_status_0>
			// 			<refund_success_time_0><![CDATA[2022-08-17 12:25:31]]></refund_success_time_0>
			// 			<result_code><![CDATA[SUCCESS]]></result_code>
			// 			<return_code><![CDATA[SUCCESS]]></return_code>
			// 			<return_msg><![CDATA[OK]]></return_msg>
			// 			<sign><![CDATA[4177253C6FEEC478EBCFDBF2FD50F398]]></sign>
			// 			<total_fee><![CDATA[100]]></total_fee>
			// 			<transaction_id><![CDATA[4200001618202208173404963998]]></transaction_id>
			// 			</xml>
			PlatformPay platformPay = platformPayService.getDefaultAccount();
			//收费的充电,并且是微信支付  才发起退款
			String retRequest = "";
			if(chargerOrder.getPayPlatform() == 0) {
				WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id, api_key);
				retRequest = wxAppPay.refundQueryAPI(chargerOrder.getOutTradeNo());
			} else {
				//String out_trade_no, PlatformPay platformPay
				retRequest = platformPayService.refundOrderQuery(chargerOrder.getRefundOutTradeNo(), platformPay);
				System.out.println("retRequest: " + retRequest);
			}

			JSONObject jsonObject = JSONUtil.parseObj(retRequest);
			if (jsonObject != null) {
				String code = "";
				String msg = "";
				String transaction_id = "",trade_no = "";
				String refundTime = "";
				double refund_fee = 0d;
				boolean bl = false;
				if(chargerOrder.getPayPlatform() == 0) {
					code = jsonObject.containsKey("code") ? jsonObject.getStr("code") : "";
					msg = jsonObject.containsKey("msg") ? jsonObject.getStr("msg") : "";
					if (code.equals("SUCCESS")) {
						bl = true;
						transaction_id = jsonObject.containsKey("transaction_id") ? jsonObject.getStr("transaction_id") : "";
						refundTime = jsonObject.containsKey("refund_success_time") ? jsonObject.getStr("refund_success_time") : "";
						refund_fee = jsonObject.containsKey("refund_fee") ? jsonObject.getDouble("refund_fee") : 0d;
						refund_fee = refund_fee / 100;
						trade_no = transaction_id;
					}
				}else{
					//{"payTime":"2022-10-13 08:35:17","connectSys":"UNIONPAY","errMsg":"查询成功","merName":"跃豆智慧生活科技（山东）有限公司",
					// "mid":"8983711651302D6","refundStatus":"FAIL","settleDate":"2022-10-13","tid":"8699CXK6","targetMid":"534866521",
					// "cardAttr":"BALANCE","targetStatus":"SUCCESS","seqId":"30138123195N","merOrderId":"32WT00000001665562150772","targetSys":"WXPay",
					// "bankInfo":"OTHERS","delegatedFlag":"N","settleRefId":"30128664338N","refundOrderId":"32WT10001665621317132","totalAmount":98,
					// "chnlCost":"758","responseTimestamp":"2022-10-13 12:35:24","errCode":"SUCCESS","status":"TRADE_CLOSED"}
					code = jsonObject.getStr("errCode");
					msg = jsonObject.getStr("errMsg");
					if (code.equals("SUCCESS")) {
						bl = true;
						transaction_id = jsonObject.containsKey("targetOrderId") ? jsonObject.getStr("targetOrderId") : "";
//						refundTime = jsonObject.containsKey("refundPayTime") ? jsonObject.getStr("refundPayTime") : "";
						refund_fee = jsonObject.containsKey("totalAmount") ? jsonObject.getDouble("totalAmount") : 0d;
						trade_no = transaction_id;
						refund_fee = refund_fee / 100;
					}
				}

				if (bl) {
					//订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
					chargerOrder.setStatus(7);
//					0 未退款 1 申请中 2 已退款  3 退款失败
					chargerOrder.setRefundStatus(2);
					chargerOrder.setRefundPrice(new BigDecimal(refund_fee));
					chargerOrder.setRefundOutTradeNo(transaction_id);
					chargerOrder.setRefundReasonTime(new Date());

					String out_trade_no = chargerOrder.getOutTradeNo();
					// 添加 微信支付的 动账记录
					QueryWrapper<WxPayTransaction> qwTrans = new QueryWrapper<>();
					qwTrans.and(wrapper->{
						wrapper.eq("transaction_no",chargerOrder.getOutTradeNo()).or().eq("transaction_id",chargerOrder.getOutTradeNo());
					});
					qwTrans.eq("fee_type","charger_refund");
					qwTrans.last("limit 1");
					WxUser user = wxUserService.findById(chargerOrder.getUserId());

					WxPayTransaction transaction = wxPayTransactionService.getOne(qwTrans);
					if(transaction == null){
						transaction = new WxPayTransaction();
						transaction.setEstateId(chargerOrder.getEstateId());
						transaction.setEstateName(chargerOrder.getEstateName());
						transaction.setTransactionNo(out_trade_no);
						transaction.setPayType(chargerOrder.getPayPlatform());// 0 -微信支付
						transaction.setTransactionId(trade_no);
						transaction.setUserId(user.getId());
						transaction.setFeeType("charger_refund");
						transaction.setTotalMoney(new BigDecimal(refund_fee ));
						transaction.setOutTradeNo(out_trade_no);
						if(StrUtil.isNotEmpty(user.getNickName())){
							transaction.setNickName(EmojiParser.parseToAliases(user.getNickName()));
						}
						transaction.setCreateTime(new Date());
						transaction.setInOrOut(0);//动账  0 - 出账 1 - 进账
						transaction.setRemark("充电费用的剩余退款");
						transaction.setPayPlatformId(chargerOrder.getPayPlatformId());
						wxPayTransactionService.save(transaction);
					}else{
						transaction.setTotalMoney(new BigDecimal(refund_fee));
						wxPayTransactionService.updateById(transaction);
					}

					ret = chargerOrderMapper.updateById(chargerOrder);
					if(ret <= 0){
						throw new TransactionalException("chargerOrderMapper updateById error");
					}
				}
			}
//			wxTemplateService.sendWxMsgEndCharger(chargerOrder);
		}catch (Exception e){
			e.printStackTrace();
		}
		return ret;
	}
}
